package ycl.important.common.utils;

import com.alibaba.fastjson.JSONObject;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

/**
 * 日期时间工具类
 *
 * @author: YCL
 * @date: 2021-06-09 23:05:08
 */
@SuppressWarnings("all")
public class DateTimeUtil {

	private static final DateTimeFormatter REGULAR_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");//常规日期
	private static final DateTimeFormatter REGULAR_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//常规日期时间
	private static final DateTimeFormatter REGULAR_DATE_TIME_MILL = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS");//常规日期时间毫秒


	private static final DateTimeFormatter ABBREVIATED_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");//缩写日期
	private static final DateTimeFormatter ABBREVIATED_DATE_TIME = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");//缩写日期时间毫秒
	private static final DateTimeFormatter ABBREVIATED_DATE_TIME_MILL = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");//缩写日期时间毫秒


	private static String getJson(Object e) {
		return JSONObject.toJSONString(e);
	}


	/**
	 * localDateTime转date
	 *
	 * @param e
	 * @return
	 */
	public static Date localDateTimeToDate(LocalDateTime e) {
		return JSONObject.parseObject(getJson(e), Date.class);
	}


	/**
	 * date转localDateTime
	 *
	 * @param e
	 * @return
	 */
	public static LocalDateTime dateToLocalDateTime(Date e) {
		return JSONObject.parseObject(getJson(e), LocalDateTime.class);
	}


	/**
	 * 常规年月日 start *******************************
	 */
	/**
	 * 获取当前日期年月日常规字符串
	 *
	 * @return
	 */
	public static String getRegularDate() {
		return getRegularDate(LocalDateTime.now());
	}

	/**
	 * date转年月日常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDate(Date e) {
		return getRegularDate(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDate(LocalDateTime e) {
		return e.format(REGULAR_DATE);
	}


	/**
	 * 常规年月日时分秒 start *******************************
	 */
	/**
	 * 获取当前日期年月日时分秒常规字符串
	 *
	 * @return
	 */
	public static String getRegularDateTime() {
		return getRegularDateTime(LocalDateTime.now());
	}

	/**
	 * date转年月日时分秒常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDateTime(Date e) {
		return getRegularDateTime(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日时分秒常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDateTime(LocalDateTime e) {
		return e.format(REGULAR_DATE_TIME);
	}


	/**
	 * 常规年月日时分秒毫秒 start *******************************
	 */
	/**
	 * 获取当前日期年月日时分秒毫秒常规字符串
	 *
	 * @return
	 */
	public static String getRegularDateTimeMill() {
		return getRegularDateTimeMill(LocalDateTime.now());
	}

	/**
	 * date转年月日时分秒毫秒常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDateTimeMill(Date e) {
		return getRegularDateTimeMill(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日时分秒毫秒常规字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getRegularDateTimeMill(LocalDateTime e) {
		return e.format(REGULAR_DATE_TIME_MILL);
	}


	/**
	 * 缩写年月日 start *******************************
	 */
	/**
	 * 获取当前日期年月日缩写字符串
	 *
	 * @return
	 */
	public static String getAbbreviatedDate() {
		return getAbbreviatedDate(LocalDateTime.now());
	}

	/**
	 * date转年月日缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDate(Date e) {
		return getAbbreviatedDate(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDate(LocalDateTime e) {
		return e.format(ABBREVIATED_DATE);
	}


	/**
	 * 缩写年月日时分秒 start *******************************
	 */
	/**
	 * 获取当前日期年月日时分秒缩写字符串
	 *
	 * @return
	 */
	public static String getAbbreviatedDateTime() {
		return getAbbreviatedDateTime(LocalDateTime.now());
	}

	/**
	 * date转年月日时分秒缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDateTime(Date e) {
		return getAbbreviatedDateTime(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日时分秒缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDateTime(LocalDateTime e) {
		return e.format(ABBREVIATED_DATE_TIME);
	}


	/**
	 * 缩写年月日时分秒毫秒 start *******************************
	 */
	/**
	 * 获取当前日期年月日时分秒毫秒缩写字符串
	 *
	 * @return
	 */
	public static String getAbbreviatedDateTimeMill() {
		return getAbbreviatedDateTimeMill(LocalDateTime.now());
	}

	/**
	 * date转年月日时分秒毫秒缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDateTimeMill(Date e) {
		return getAbbreviatedDateTimeMill(dateToLocalDateTime(e));
	}

	/**
	 * LocalDateTime转年月日时分秒毫秒缩写字符串
	 *
	 * @param e
	 * @return
	 */
	public static String getAbbreviatedDateTimeMill(LocalDateTime e) {
		return e.format(ABBREVIATED_DATE_TIME_MILL);
	}


	/**
	 * 判断是否今天
	 *
	 * @param e
	 * @return
	 */
	public static int today(LocalDateTime e) {
		if (e == null)
			return 0;
		LocalDate now = LocalDate.now();
		LocalDateTime start = now.atTime(0, 0, 0);
		LocalDateTime end = now.atTime(23, 59, 59);
		return e.isBefore(start) ? - 1 : (e.isBefore(end) ? 0 : 1);
	}

	/**
	 * 判断时间是否今天
	 *
	 * @param e
	 * @return
	 */
	public static int today(Date e) {
		return today(dateToLocalDateTime(e));
	}


	/**
	 * 获取某个时间几天后的时间戳
	 * (有bug, 留意, 切切)
	 *
	 * @param e
	 * @param days
	 * @return
	 */
	public static long getTimestampAfterDays(LocalDateTime e, int days) {
		if (e == null)
			throw new IllegalArgumentException("target date is null ! ");
		int t = 24 * 60 * 60 * days;
		long l = e.toInstant(ZoneOffset.of("+8")).toEpochMilli();
		return l + t;
	}

	/**
	 * 获取某个时间几天后的日期
	 *
	 * @param e
	 * @param days
	 * @return
	 */
	public static LocalDateTime getDateAfterDays(LocalDateTime e, int days) {
		if (days == 0)
			return e;
		long result = getTimestampAfterDays(e, days);
		return timestampToLocalDateTime(result);
	}

	/**
	 * 时间戳转 LocalDateTime
	 *
	 * @param timestamp
	 * @return
	 */
	public static LocalDateTime timestampToLocalDateTime(long timestamp) {
		return LocalDateTime.ofEpochSecond(timestamp, 0, ZoneOffset.of("8"));
	}


	/**
	 * 获取当月第一天
	 *
	 * @return
	 */
	public static LocalDateTime getFirstDayForMonth() {
		LocalDateTime now = LocalDateTime.now();
		return now.with(TemporalAdjusters.firstDayOfMonth());
	}


	/**
	 * 获取当月最后一天
	 *
	 * @return
	 */
	public static LocalDateTime getLastDayForMonth() {
		LocalDateTime now = LocalDateTime.now();
		return now.with(TemporalAdjusters.lastDayOfMonth());
	}
}
